#include "car.h"

Car::Car()
{ }

Car::Car(b2World* p_gameWorld, b2Vec2 position)
{ 
	connectToGameWorld(p_gameWorld);
	buildCar(position);
	disconnectFromGameWorld();
}

Car::~Car()
{ }

void Car::connectToGameWorld(b2World* p_gameWorld)
{
	ap_gameWorld = p_gameWorld;
}

void Car::buildCar(b2Vec2 position)
{
	createChassis(position);
	createWheels();
	createJoints();
	prepareMotors();
}

void Car::disconnectFromGameWorld()
{
	ap_gameWorld = NULL;
}

void Car::createChassis(b2Vec2 position)
{
	b2BodyDef bodyDef;
	bodyDef.type = b2_dynamicBody;
	bodyDef.position.Set(position.x, position.y);
	ap_chassis = ap_gameWorld->CreateBody(&bodyDef);

	b2PolygonShape chassis;
	chassis.SetAsBox(0.3f, 0.04f);
	ap_chassis->CreateFixture(&chassis, 1.0f);
}

void Car::createWheels()
{
	b2BodyDef bodyDef;
	bodyDef.type = b2_dynamicBody;
	b2CircleShape wheelShape;
	wheelShape.m_radius = 0.1f;
	b2FixtureDef wheelFixture;
	wheelFixture.shape = &wheelShape;
	wheelFixture.density = 1.0f;
	wheelFixture.friction = 2.0f;
	bodyDef.position.Set(ap_chassis->GetPosition().x + 0.3f,
						 ap_chassis->GetPosition().y       );
	ap_frontWheel = ap_gameWorld->CreateBody(&bodyDef);
	ap_frontWheel->CreateFixture(&wheelFixture);
	bodyDef.position.Set(ap_chassis->GetPosition().x - 0.3f,
						 ap_chassis->GetPosition().y       );
	ap_backWheel = ap_gameWorld->CreateBody(&bodyDef);
	ap_backWheel->CreateFixture(&wheelFixture);
}

void Car::createJoints()
{
	b2RevoluteJointDef revjointDef;
	revjointDef.Initialize(ap_chassis,
						   ap_backWheel, 
						   b2Vec2(
						   ap_backWheel->GetPosition().x, 
						   ap_backWheel->GetPosition().y));
	ap_gameWorld->CreateJoint(&revjointDef);
	ap_backWheelJoint = (b2RevoluteJoint*)ap_gameWorld->CreateJoint(&revjointDef);

	revjointDef.Initialize(ap_chassis,
						   ap_frontWheel, 
						   b2Vec2(
						   ap_frontWheel->GetPosition().x, 
						   ap_frontWheel->GetPosition().y));
	ap_frontWheelJoint = (b2RevoluteJoint*)ap_gameWorld->CreateJoint(&revjointDef);
}

void Car::prepareMotors()
{
	ap_frontWheelJoint->SetMotorSpeed(0.0f);
	ap_frontWheelJoint->SetMaxMotorTorque(2000.0f);
	ap_frontWheelJoint->EnableMotor(false);

	ap_backWheelJoint->SetMotorSpeed(0.0f);
	ap_backWheelJoint->SetMaxMotorTorque(2000.0f);
	ap_backWheelJoint->EnableMotor(false);
}

b2Vec2 Car::getCarPosition()
{
	return ap_chassis->GetPosition();
}

void Car::turnMotorsOnWith(float32 speed)
{
	ap_frontWheelJoint->EnableMotor(true);
	ap_frontWheelJoint->SetMotorSpeed(speed);
	ap_backWheelJoint->EnableMotor(true);
	ap_backWheelJoint->SetMotorSpeed(speed);
}

void Car::turnMotorsOff()
{
	ap_frontWheelJoint->EnableMotor(false);
	ap_backWheelJoint->EnableMotor(false);
}

void Car::brake()
{
	ap_frontWheelJoint->EnableMotor(true);
	ap_frontWheelJoint->SetMotorSpeed(0.0f);
	ap_backWheelJoint->EnableMotor(true);
	ap_backWheelJoint->SetMotorSpeed(0.0f);
}

